package cn.iocoder.yudao.module.scrm.service.approve;

import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.scrm.controller.admin.approve.vo.ApproveReqVO;
import cn.iocoder.yudao.module.scrm.controller.admin.approve.vo.ApproveRespVO;
import cn.iocoder.yudao.module.scrm.dal.dataobject.invoice.InvoiceDO;
import cn.iocoder.yudao.module.scrm.dal.dataobject.receivable.ReceivableDO;
import cn.iocoder.yudao.module.scrm.dal.dataobject.refund.RefundDO;
import cn.iocoder.yudao.module.scrm.dal.mysql.invoice.InvoiceMapper;
import cn.iocoder.yudao.module.scrm.dal.mysql.receivable.ReceivableMapper;
import cn.iocoder.yudao.module.scrm.dal.mysql.refund.RefundMapper;
import cn.iocoder.yudao.module.scrm.enums.common.CrmBizTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.util.concurrent.TimeUnit;

import static cn.iocoder.yudao.module.scrm.enums.common.CrmBizTypeEnum.getEnumByType;

/**
 * @description 审批服务实现类
 */
@Service
@Slf4j
public class ApproveServiceImpl implements ApproveService {

    @Resource
    private InvoiceMapper invoiceMapper;

    @Resource
    private ReceivableMapper receivableMapper;

    @Resource
    private RefundMapper refundMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public ApproveRespVO approve(ApproveReqVO approveReqVO) {
        log.info("处理审批业务类型: {}", approveReqVO.getBizType());
        ApproveRespVO respVO;

        switch (getEnumByType(approveReqVO.getBizType())) {
            case CRM_INVOICE:
                respVO = updateStatus(invoiceMapper, InvoiceDO::getId, InvoiceDO::getProcessInstanceId, InvoiceDO::getAuditStatus, approveReqVO);
                break;
            case CRM_RECEIVABLE:
                respVO = updateStatus(receivableMapper, ReceivableDO::getId, ReceivableDO::getProcessInstanceId, ReceivableDO::getAuditStatus, approveReqVO);
                break;
            case CRM_REFUND:
                respVO = updateStatus(refundMapper, RefundDO::getId, RefundDO::getProcessInstanceId, RefundDO::getAuditStatus, approveReqVO);
                break;
            default:
                return new ApproveRespVO(false, 0);
        }
        log.info("审批完成，业务ID: {}", approveReqVO.getBizId());
        return respVO;
    }

    private <T> ApproveRespVO updateStatus(BaseMapper<T> mapper,
                                  SFunction<T, ?> idGetter,
                                  SFunction<T, ?> processInstanceIdGetter,
                                  SFunction<T, ?> auditStatusGetter,
                                  ApproveReqVO approveReqVO) {
        if(ObjectUtil.isNull(approveReqVO.getId())){
            // 查询当前状态
            T entity = mapper.selectOne(new LambdaQueryWrapper<T>()
                    .eq(approveReqVO.getId() != null, idGetter, approveReqVO.getId())
                    .eq(approveReqVO.getId() == null, processInstanceIdGetter, approveReqVO.getBizId())
                    .select(auditStatusGetter)
            );

            Integer currentStatus = null;
            if (entity instanceof InvoiceDO) {
                currentStatus = ((InvoiceDO) entity).getAuditStatus();
            } else if (entity instanceof ReceivableDO) {
                currentStatus = ((ReceivableDO) entity).getAuditStatus();
            } else if (entity instanceof RefundDO) {
                currentStatus = ((RefundDO) entity).getAuditStatus();
            }

            // 检查审批状态是否为1（审批中）
            if (currentStatus == null || currentStatus != 1) {
                stringRedisTemplate.opsForValue().set(String.valueOf(approveReqVO.getBizId()), String.valueOf(approveReqVO.getApproveStatus()), 30, TimeUnit.SECONDS);
                log.warn("审批状态不在审批中状态，业务ID: {}", approveReqVO.getBizId());
                return new ApproveRespVO(false, 0);
            }
        } else {
            // 判断redis中是否有缓存,用是否包含key值判断
            if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(String.valueOf(approveReqVO.getBizId())))) {
                String approveStatus = stringRedisTemplate.opsForValue().get(String.valueOf(approveReqVO.getBizId()));
                if (approveStatus != null) {
                    approveReqVO.setApproveStatus(Integer.parseInt(approveStatus));
                    // 删除缓存
                    stringRedisTemplate.delete(String.valueOf(approveReqVO.getBizId()));
                }
            }
        }
        LambdaUpdateWrapper<T> updateWrapper = new LambdaUpdateWrapper<T>()
                .eq(approveReqVO.getId() != null, idGetter, approveReqVO.getId())
                .eq(approveReqVO.getId() == null, processInstanceIdGetter, approveReqVO.getBizId())
                .set(processInstanceIdGetter, approveReqVO.getBizId())
                .set(auditStatusGetter, approveReqVO.getApproveStatus());

        int count = mapper.update(null, updateWrapper);
        return new ApproveRespVO(true, count);
    }
}
